import 'package:date_format/date_format.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:keep_accounts/entity/period.dart';
import 'package:keep_accounts/routes.dart';
import 'package:keep_accounts/widgets/base_widgets.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

import 'entity/user.dart';
import 'entity/work_record.dart';
import 'helper/flutter_log.dart';
import 'main.dart';
import 'objectbox.g.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key, required this.title});

  final String title;

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  final Rx<DateTime> _currentDate = DateTime.now().obs;

  final Rx<TimeOfDay> _startTime1 = const TimeOfDay(hour: 9, minute: 0).obs;
  final Rx<TimeOfDay> _startTime2 = const TimeOfDay(hour: 13, minute: 0).obs;
  final Rx<TimeOfDay> _endTime1 = const TimeOfDay(hour: 12, minute: 0).obs;
  final Rx<TimeOfDay> _endTime2 = const TimeOfDay(hour: 15, minute: 0).obs;
  final RxBool _period1Checked = false.obs;
  final RxBool _period2Checked = false.obs;

  late Box<WorkRecord> _recordBox;
  late Box<User> _userBox;
  late Box<User> _periodBox;
  final RxList<WorkRecord> _recordList = <WorkRecord>[].obs;
  final RxList<User> _userList = <User>[].obs;
  final _defaultUsername = '添加用户';
  late Rx<User> _currentUser;

  final RefreshController _refreshController = RefreshController(initialRefresh: false);
  final ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _currentUser = (User()..username = _defaultUsername).obs;
    _recordBox = objectBox.store.box<WorkRecord>();
    _userBox = objectBox.store.box<User>();
    _refreshUser();
    if(_userList.isNotEmpty) {
      _currentUser.value = _userList[0];
    }
  }

  Query<WorkRecord> _buildQuery() {
    var start = DateTime(
      _currentDate.value.year,
      _currentDate.value.month,
      1
    ).millisecondsSinceEpoch; // 本月第一天
    var end = DateTime(
      _currentDate.value.year,
      _currentDate.value.month + 1,
      0,
      23,
      59,
      59
    ).millisecondsSinceEpoch; // 本月最后一天
    var conditions = WorkRecord_.id.greaterOrEqual(0);
    conditions = conditions.and(WorkRecord_.user.equals(_currentUser.value.id));
    conditions = conditions.and(WorkRecord_.dateTime.between(start, end));

    QueryBuilder<WorkRecord> builder = _recordBox.query(conditions);

    builder.order(WorkRecord_.dateTime, flags: Order.descending);
    builder.order(WorkRecord_.modifyTime, flags: Order.descending);

    return builder.build();
  }

  void _refreshUser() {
    List<User> userList = _userBox.getAll();
    flog("user count is ${userList.length}");
    if(userList.isNotEmpty) {
      _userList.assignAll(userList);
      _userList.refresh();
      if(_currentUser.value.username == _defaultUsername) {
        _currentUser.value = _userList[0];
      }
    }
  }

  Future<void> _refreshRecords() async {
    Query<WorkRecord> query = _buildQuery();
    List<WorkRecord> records = query.find();
    query.close();
    flog("records count is ${records.length}");
    _recordList.assignAll(records);
  }

  Future<void> _onRefresh() async {
    _refreshRecords();
    _refreshController.loadComplete();
    _refreshController.refreshCompleted();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Obx(() => _buildUser()),
        centerTitle: true,
        actions: [
          InkWell(
            onTap: () {
              Get.toNamed(Routes.addUser)?.then((value) => _refreshUser());
            },
            child: const Icon(Icons.add_circle_outline, size: 30,), // 添加用户
          ),
          const SizedBox(width: 15,),
        ],
      ),
      body: Obx(() => _buildBody()),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
        },
        child: const Icon(Icons.add),
      ),
    );
  }

  Widget _buildBody() {
    return Column(
      children: <Widget>[
        _buildAddWorkPeriodRegion(),
        Expanded(
          child: SmartRefresher(
            enablePullDown: true,
            controller: _refreshController,
            onRefresh: _onRefresh,
            child: _buildList(),
          ),
        ),
      ],
    );
  }

  /// 顶部 用户按钮
  Widget _buildUser() {
    return PopupMenuButton<User>(
      onSelected: (User item) {
        flog(item.toString());
        _currentUser.value = item;
        _onRefresh();
      },
      position: PopupMenuPosition.under,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(5),
      ),
      itemBuilder: (BuildContext context) {
        return List.generate(_userList.length, (index) {
          User item = _userList[index];
          if (index % 2 == 0) {
            return PopupMenuItem(
              value: item,
              child: Container(
                width: double.infinity,
                padding: const EdgeInsets.all(10),
                child: Text(
                  item.username ?? "",
                  textAlign: TextAlign.center,
                  style: const TextStyle(
                    fontSize: 16,
                    color: Colors.black45,
                  ),
                ),
              ),
            );
          } else {
            return const PopupMenuDivider(height: 1,);
          }
        });
      },
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          _currentUser.value.username == _defaultUsername
              ? InkWell(
                  onTap: () {
                    Get.toNamed(Routes.addUser)
                        ?.then((value) => _refreshUser());
                  },
                  child: Text(_currentUser.value.username),
                )
              : Text(_currentUser.value.username),
          const Icon(Icons.arrow_drop_down_sharp),
        ],
      ),
    );
  }

  String format(TimeOfDay time) {
    return '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
  }

  Widget _buildAddWorkPeriodRegion() {
    Duration calcHours(TimeOfDay start, TimeOfDay end) {
      var endHours = end.hour + end.minute / 60.0;
      var startHours = start.hour + start.minute / 60.0;
      var diff = endHours - startHours;
      var diffHour = diff.truncate();
      int diffMinute = ((diff - diffHour) * 60).toInt();

      return Duration(hours: diffHour, minutes: diffMinute);
    }

    return Container(
      padding: const EdgeInsets.all(10),
      margin: const EdgeInsets.all(10),
      decoration: BoxDecoration(
        border: Border.all(color: Colors.purpleAccent),
        borderRadius: const BorderRadius.all(Radius.circular(10)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              const Text(
                '日期：',
                style: TextStyle(
                  fontSize: 20,
                ),
              ),
              InkWell(
                onTap: () async {
                  DateTime? dateTime = await showDatePicker(
                    context: context,
                    initialDate: DateTime.now(),
                    firstDate: DateTime(1900, 01, 01),
                    lastDate: DateTime.now(),
                    locale: const Locale('zh'),
                  );
                  if(dateTime != null) {
                    _currentDate.value = dateTime;
                    _onRefresh();
                  }
                },
                child: Text(
                    formatDate(_currentDate.value, [yyyy, '年', mm, '月', dd, '日']),
                  style: const TextStyle(
                    fontSize: 20,
                  ),
                ),
              ),
            ],
          ),
          Row(
            children: [
              const Text(
                '上午：',
                style: TextStyle(
                  fontSize: 20,
                ),
              ),
              InkWell(
                onTap: () async {
                  TimeOfDay? timeOfDay = await _selectTime(_startTime1.value);
                  if (timeOfDay != null) {
                    _startTime1.value = timeOfDay;
                  }
                },
                child: Text(
                  format(_startTime1.value),
                  style: const TextStyle(
                    fontSize: 20,
                  ),
                ),
              ),
              const SizedBox(width: 10,),
              const Text(
                '至',
                style: TextStyle(
                  fontSize: 20,
                ),
              ),
              const SizedBox(width: 10,),
              InkWell(
                onTap: () async {
                  TimeOfDay? timeOfDay = await _selectTime(_endTime1.value);
                  if (timeOfDay != null) {
                    _endTime1.value = timeOfDay;
                  }
                },
                child: Text(
                  format(_endTime1.value),
                  style: const TextStyle(
                    fontSize: 20,
                  ),
                ),
              ),
              const SizedBox(width: 10,),
              Text(
                "${calcHours(_startTime1.value, _endTime1.value).inHours}小时",
                style: const TextStyle(
                  color: Colors.red,
                  fontSize: 20,
                ),
              ),
              Checkbox(
                value: _period1Checked.value,
                onChanged: (bool? value) { _period1Checked.value = value ?? false; },
              ),
            ],
          ),
          Row(
            children: [
              const Text(
                '下午：',
                style: TextStyle(
                  fontSize: 20,
                ),
              ),
              InkWell(
                onTap: () async {
                  TimeOfDay? timeOfDay = await _selectTime(_startTime2.value);
                  if (timeOfDay != null) {
                    _startTime2.value = timeOfDay;
                  }
                },
                child: Text(
                  format(_startTime2.value),
                  style: const TextStyle(
                    fontSize: 20,
                  ),
                ),
              ),
              const SizedBox(width: 10,),
              const Text(
                '至',
                style: TextStyle(
                  fontSize: 20,
                ),
              ),
              const SizedBox(width: 10,),
              InkWell(
                onTap: () async {
                  TimeOfDay? timeOfDay = await _selectTime(_endTime2.value);
                  if (timeOfDay != null) {
                    _endTime2.value = timeOfDay;
                  }
                },
                child: Text(
                  format(_endTime2.value),
                  style: const TextStyle(
                    fontSize: 20,
                  ),
                ),
              ),
              const SizedBox(width: 10,),
              Text(
                "${calcHours(_startTime2.value, _endTime2.value).inHours}小时",
                style: const TextStyle(
                  color: Colors.red,
                  fontSize: 20,
                ),
              ),
              Checkbox(
                value: _period2Checked.value,
                onChanged: (bool? value) { _period2Checked.value = value ?? false; },
              ),
            ],
          ),
          Container(
            width: double.infinity,
            margin: const EdgeInsets.only(left: 20, right: 20),
            child: ElevatedButton(
              onPressed: () {
                if(!_period1Checked.value && !_period2Checked.value) {
                  Fluttertoast.showToast(msg: '请至少选择一个时间段');
                  return;
                }
                _addWorkPeriod(_startTime1.value, _endTime1.value,
                    _startTime2.value, _endTime2.value);
              },
              child: const Padding(
                padding: EdgeInsets.all(10),
                child: Text(
                  '添加时间段',
                  style: TextStyle(fontSize: 18),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Future<TimeOfDay?> _selectTime(TimeOfDay init) async {
    return await showTimePicker(
      context: context,
      initialTime: init
    );
  }

  void _addWorkPeriod(TimeOfDay start1, TimeOfDay end1, TimeOfDay start2, TimeOfDay end2) {
    WorkRecord record = WorkRecord();
    record.user.targetId = _currentUser.value.id;
    record.dateTime = _currentDate.value.millisecondsSinceEpoch;
    if(_period1Checked.value) {
      DateTime startTime1 = _timeOfDay2DateTime(_currentDate.value, start1);
      DateTime endTime1 = _timeOfDay2DateTime(_currentDate.value, end1);
      Period period = Period()
        ..startTime = startTime1.millisecondsSinceEpoch
        ..endTime = endTime1.millisecondsSinceEpoch
        ..dayPeriod = DayPeriod.am.name;
      record.periods.add(period);
    }
    if(_period2Checked.value) {
      DateTime startTime2 = _timeOfDay2DateTime(_currentDate.value, start2);
      DateTime endTime2 = _timeOfDay2DateTime(_currentDate.value, end2);
      Period period = Period()
        ..startTime = startTime2.millisecondsSinceEpoch
        ..endTime = endTime2.millisecondsSinceEpoch
        ..dayPeriod = DayPeriod.pm.name;
      record.periods.add(period);
    }
    _recordBox.put(record);
    _onRefresh();
  }

  DateTime _timeOfDay2DateTime(DateTime date, TimeOfDay timeOfDay) {
    return DateTime(
        date.year, date.month, date.day, timeOfDay.hour, timeOfDay.minute);
  }


  Widget _buildList1() {
    return Obx(() => ListView.separated(
      shrinkWrap: true,
      controller: _scrollController,
      itemBuilder: (context, index) {
        WorkRecord record = _recordList[index];
        return _listTile(index);
      },
      itemCount: _recordList.length,
      separatorBuilder: (BuildContext context, int index) => BaseWidgets.dividerIndent(),
    ));
  }

  Widget _buildList() {
    return CustomScrollView(
      slivers: [
        SliverList(
          delegate: SliverChildBuilderDelegate(
              childCount: _recordList.length,
              (context, index) => _listTile(index)),
        ),
      ],
    );
  }

  Widget _listTile(int index) {
    if(_recordList.isEmpty) {
      return const SizedBox(width: 10,height: 10,);
    }
    WorkRecord record = _recordList[index];
    return Slidable(
      key: ValueKey(record),
      groupTag: "0",
      closeOnScroll: true,
      endActionPane: ActionPane(
        extentRatio: 0.2,
        motion: const ScrollMotion(),
        children: [
          SlidableAction(
            onPressed: (BuildContext context) {
              record.periods.clear();
              _recordBox.put(record);
              _recordBox.remove(record.id);
              _recordList.removeWhere((element) => element.id == record.id);
              _recordList.refresh();
            },
            backgroundColor: const Color(0xFFFA5151),
            foregroundColor: Colors.white,
            label: '删除',
          ),
        ],
      ),
      child: Container(
        padding: const EdgeInsets.all(15),
        child: InkWell(
          onTap: () {
          },
          child: _buildItem(record),
        ),
      ),
    );
  }

  Widget _buildItem(WorkRecord record) {
    return Row(
      children: [
        Text(
          DateFormat("MM-dd").format(DateTime.fromMillisecondsSinceEpoch(record.dateTime)),
          style: const TextStyle(
            fontWeight: FontWeight.bold,
          ),
        ),
        const SizedBox(width: 15,),
        Expanded(
          child: Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Text(
                    "上午：",
                    style: TextStyle(
                      fontSize: 16,
                    ),
                  ),
                  Text(
                    record.periodStr(DayPeriod.am, context),
                    style: const TextStyle(
                      fontSize: 16,
                    ),
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Text(
                    "下午：",
                    style: TextStyle(
                      fontSize: 16,
                    ),
                  ),
                  Text(
                    record.periodStr(DayPeriod.pm, context),
                    style: const TextStyle(
                      fontSize: 16,
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
        // const Spacer(),
        const SizedBox(width: 10,),
        Text(
          "${record.periodsDuration().inHours}小时",
          style: const TextStyle(
            color: Colors.red,
            fontSize: 16,
          ),
        ),
      ],
    );
  }
}